﻿using System;
using System.Collections;
using System.Data;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
namespace eTMS.UpdateServices
{
    public class UpdateService : ServiceBase, IUpdateService
    {
        public static string RootPath = "";
        public UpdateService()
        {
            //Uncomment the following line if using designed components 
            //InitializeComponent(); 
        }
        public string GetFilesPath()
        {
            return System.Configuration.ConfigurationSettings.AppSettings["UpdatePath"].Replace("~/", "");
        }
        private string GetUpdatePath()
        {
            return System.Configuration.ConfigurationSettings.AppSettings["UpdatePath"].Replace("~", RootPath).TrimEnd('\\').Replace("/", "\\");
        }
        private string GetServicePath()
        {
            return Path.GetDirectoryName(RootPath);
        }
        private string GetFileList()
        {
            string path = GetUpdatePath();
            return path + "\\list.xml";
        }
        public DataSet GetAllUpdateableComponents()
        {
            DataSet ds = GetUpdateDataSet();
            DataTable tbl = ds.Tables[0];
            tbl.DefaultView.RowFilter = "Enabled=true";
            ds.Tables.RemoveAt(0);
            ds.Tables.Add(tbl.DefaultView.ToTable());
            return ds;
        }
        public DataSet GetUpdateDataSet()
        {
            DataSet ds = null;
            string fileName = GetFileList();
            if (File.Exists(fileName))
            {
                ds = new DataSet();
                ds.ReadXml(fileName, XmlReadMode.ReadSchema);
            }
            if (ds == null)
            {
                ds = new DataSet();
                ds.Tables.Add();
                ds.Tables[0].Columns.Add("Path");
                ds.Tables[0].Columns.Add("Version", typeof(int));
                ds.Tables[0].Columns.Add("Enabled", typeof(bool));
            }
            return ds;
        }
        public void EnableUpdate(string path)
        {
            DataSet ds = GetUpdateDataSet();
            DataRow[] rs = ds.Tables[0].Select("Path='" + path + "'");
            if (rs.Length > 0)
            {
                rs[0]["Enabled"] = true;
            }
            ds.WriteXml(GetFileList(), XmlWriteMode.WriteSchema);
        }
        public void DeleteFile(List<string> lspath)
        {
            string updatepath = GetUpdatePath();
            DataSet ds = GetUpdateDataSet();
            foreach (string path in lspath)
            {
                DataRow[] rs = ds.Tables[0].Select("Path='" + path + "'");
                if (rs.Length > 0)
                {
                    if (File.Exists(updatepath + "\\" + path))
                    {
                        File.Delete(updatepath + "\\" + path);
                    }
                    ds.Tables[0].Rows.Remove(rs[0]);
                }
            }
            ds.WriteXml(GetFileList(), XmlWriteMode.WriteSchema);
        }
        public void SaveComponents(byte[] buff, bool isAppend, bool isFinish, string fileName)
        {
            string fullName = GetUpdatePath() + "\\" + fileName;
            FileStream strm;
            if (isAppend)
            {
                strm = File.Open(fullName, FileMode.Append, FileAccess.Write);
            }
            else
            {
                string filePath = Path.GetDirectoryName(fullName);
                if (!Directory.Exists(filePath))
                    Directory.CreateDirectory(filePath);
                strm = File.Create(fullName);
            }
            strm.Write(buff, 0, buff.Length);
            strm.Close();
            if (isFinish)
            {
                DataSet ds = GetUpdateDataSet();
                DataRow[] rs = ds.Tables[0].Select("Path='" + fileName + "'");
                if (rs.Length > 0)
                {
                    rs[0]["Version"] = int.Parse(rs[0]["Version"].ToString()) + 1;
                }
                else
                {
                    DataRow row = ds.Tables[0].NewRow();
                    row["Path"] = fileName;
                    row["Version"] = 1;
                    row["Enabled"] = true;
                    ds.Tables[0].Rows.Add(row);
                }
                ds.WriteXml(GetFileList(), XmlWriteMode.WriteSchema);
            }
        }
        public void StopServer()
        {
            Process p = Process.Start(RootPath + "\\Stop.bat");
            p.WaitForExit();
        }
        public void StartServer()
        {
            Process p = Process.Start(RootPath + "\\Start.bat");
            p.WaitForExit();
        }
        public void SaveServerService(byte[] buff, bool isAppend, bool isFinish, string fileName)
        {
            string fullName = GetServicePath() + "\\" + fileName;
            FileStream strm;
            if (isAppend)
            {
                strm = File.Open(fullName, FileMode.Append, FileAccess.Write);
            }
            else
            {
                string filePath = Path.GetDirectoryName(fullName);
                if (!Directory.Exists(filePath))
                    Directory.CreateDirectory(filePath);
                strm = File.Create(fullName);
            }
            strm.Write(buff, 0, buff.Length);
            strm.Close();
        }
        const int FILE_PACKSIZE = 512000;
        public int GetPacketCount(string fileName)
        {
            string fullName = GetUpdatePath() + "\\" + fileName;
            FileInfo f = new FileInfo(fullName);
            if (f.Exists)
            {
                return (int)Math.Ceiling((double)f.Length / (double)FILE_PACKSIZE);
            }
            return 0;
        }
        public byte[] GetComponents(int partindex, string fileName)
        {
            byte[] buff;
            string fullName = GetUpdatePath() + "\\" + fileName;
            string key = fileName + "_" + partindex.ToString();
            if (!Cache.IsSet(key))
            {
                FileStream strm = File.Open(fullName, FileMode.Open, FileAccess.Read, FileShare.Read);
                if (partindex * FILE_PACKSIZE >= strm.Length)
                {
                    strm.Close();
                    return null;
                }
                strm.Position = partindex * FILE_PACKSIZE;
                buff = new byte[FILE_PACKSIZE];
                int len = strm.Read(buff, 0, FILE_PACKSIZE);
                byte[] tmp = buff;
                if ((len < FILE_PACKSIZE) || (strm.Position == strm.Length))
                {
                    tmp = new byte[len];
                    Array.Copy(buff, tmp, tmp.Length);
                }
                strm.Close();
                lock (this)
                {
                    if (!Cache.IsSet(key))
                        Cache.Set(key, tmp, CacheTimeOut);
                }
                buff = tmp;
            }
            else
            {
                buff = Cache.Get<byte[]>(key);
            }
            return buff;

        }

      
    }

}